package com.rc.evcharger.config;

/**
 * 异步配置，@EnableAsync 检测@Async注解,开启异步方法
 * Created by Sven on 2021/06/28
 */

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

@Configuration
@EnableAsync
public class SpringAsyncConfig {

    /**
     * A4心跳线程池
     */
    @Value("${heartBeat.thread.pool.corePoolSize}") //设置默认值2
    private int hearBeatCorePoolSize;
    @Value("${heartBeat.thread.pool.maxPoolSize}") //设置默认值8
    private int hearBeatMaxPoolSize;
    @Value("${heartBeat.thread.pool.queueCapacity}") //设置默认值2
    private int hearBeatQueueCapacity;
    @Value("${heartBeat.thread.pool.keepAliveSeconds}") //设置默认值8
    private int hearBeatKeepAliveSeconds;

    /**
     * A5充电中线程池
     */
    @Value("${thread.pool.corePoolSize:2}") //设置默认值2
    private int corePoolSize;
    @Value("${thread.pool.maxPoolSize:4}") //设置默认值8
    private int maxPoolSize;
    @Value("${thread.pool.queueCapacity}") //设置默认值2
    private int queueCapacity;
    @Value("${thread.pool.keepAliveSeconds}") //设置默认值8
    private int keepAliveSeconds;


    //1、corePoolSize：核心线程数
    //   * 核心线程会一直存活，及时没有任务需要执行
    //   * 当线程数小于核心线程数时，即使有线程空闲，线程池也会优先创建新线程处理
    //   * 设置allowCoreThreadTimeout=true（默认false）时，核心线程会超时关闭

    //2、maxPoolSize：最大线程数
    //    * 当线程数>=corePoolSize，且任务队列已满时。线程池会创建新线程来处理任务
    //    * 当线程数=maxPoolSize，且任务队列已满时，线程池会拒绝处理任务而抛出异常

    /**
     * 处理A4 心跳异步线程
     * @return
     */
    @Bean("taskExecutor1")
    public Executor taskExecutor1() {
        //自定义线程池
        ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
        pool.setCorePoolSize(hearBeatCorePoolSize); //线程池活跃的线程数,若池中的实际线程数小于该值，无论其中是否有空闲的线程，都会产生新的线程
        pool.setMaxPoolSize(hearBeatMaxPoolSize); //线程池最大活跃的线程数
        //pool.setMaxPoolSize(Integer.MAX_VALUE); //无边界
        pool.setQueueCapacity(hearBeatQueueCapacity);  //<!-- 阻塞队列的容量大小 -->
        pool.setKeepAliveSeconds(hearBeatKeepAliveSeconds);  //<!-- 允许的空闲时间 -->
        pool.setWaitForTasksToCompleteOnShutdown(true);
        /**
         * Reject策略预定义有四种：
         * (1)ThreadPoolExecutor.AbortPolicy策略，是默认的策略,处理程序遭到拒绝将抛出运行时 RejectedExecutionException。
         * (2)ThreadPoolExecutor.CallerRunsPolicy策略 ,调用者的线程会执行该任务,如果执行器已关闭,则丢弃.
         * (3)ThreadPoolExecutor.DiscardPolicy策略，不能执行的任务将被丢弃.
         * (4)ThreadPoolExecutor.DiscardOldestPolicy策略，如果执行程序尚未关闭，则位于工作队列头部的任务将被删除，然后重试执行程序（如果再次失败，则重复此过程）.
         */
        pool.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        pool.setThreadNamePrefix("domain1-");//线程名称前缀
        return pool;
    }


    /**
     * 处理A4 心跳异步线程
     * @return
     */
    @Bean("taskExecutor2")
    public Executor taskExecutor2() {
        //自定义线程池
        ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
        pool.setCorePoolSize(hearBeatCorePoolSize); //线程池活跃的线程数,若池中的实际线程数小于该值，无论其中是否有空闲的线程，都会产生新的线程
        pool.setMaxPoolSize(hearBeatMaxPoolSize); //线程池最大活跃的线程数
        //pool.setMaxPoolSize(Integer.MAX_VALUE); //无边界
        pool.setQueueCapacity(hearBeatQueueCapacity);  //<!-- 阻塞队列的容量大小 -->
        pool.setKeepAliveSeconds(hearBeatKeepAliveSeconds);  //<!-- 允许的空闲时间 -->
        pool.setWaitForTasksToCompleteOnShutdown(true);
        /**
         * Reject策略预定义有四种：
         * (1)ThreadPoolExecutor.AbortPolicy策略，是默认的策略,处理程序遭到拒绝将抛出运行时 RejectedExecutionException。
         * (2)ThreadPoolExecutor.CallerRunsPolicy策略 ,调用者的线程会执行该任务,如果执行器已关闭,则丢弃.
         * (3)ThreadPoolExecutor.DiscardPolicy策略，不能执行的任务将被丢弃.
         * (4)ThreadPoolExecutor.DiscardOldestPolicy策略，如果执行程序尚未关闭，则位于工作队列头部的任务将被删除，然后重试执行程序（如果再次失败，则重复此过程）.
         */
        pool.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        pool.setThreadNamePrefix("domain2-");//线程名称前缀
        return pool;
    }


    /**
     * 处理A4 心跳异步线程
     * @return
     */
    @Bean("taskExecutor3")
    public Executor taskExecutor3() {
        //自定义线程池
        ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
        pool.setCorePoolSize(hearBeatCorePoolSize); //线程池活跃的线程数,若池中的实际线程数小于该值，无论其中是否有空闲的线程，都会产生新的线程
        pool.setMaxPoolSize(hearBeatMaxPoolSize); //线程池最大活跃的线程数
        //pool.setMaxPoolSize(Integer.MAX_VALUE); //无边界
        pool.setQueueCapacity(hearBeatQueueCapacity);  //<!-- 阻塞队列的容量大小 -->
        pool.setKeepAliveSeconds(hearBeatKeepAliveSeconds);  //<!-- 允许的空闲时间 -->
        pool.setWaitForTasksToCompleteOnShutdown(true);
        /**
         * Reject策略预定义有四种：
         * (1)ThreadPoolExecutor.AbortPolicy策略，是默认的策略,处理程序遭到拒绝将抛出运行时 RejectedExecutionException。
         * (2)ThreadPoolExecutor.CallerRunsPolicy策略 ,调用者的线程会执行该任务,如果执行器已关闭,则丢弃.
         * (3)ThreadPoolExecutor.DiscardPolicy策略，不能执行的任务将被丢弃.
         * (4)ThreadPoolExecutor.DiscardOldestPolicy策略，如果执行程序尚未关闭，则位于工作队列头部的任务将被删除，然后重试执行程序（如果再次失败，则重复此过程）.
         */
        pool.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        pool.setThreadNamePrefix("domain3-");//线程名称前缀
        return pool;
    }

    /**
     * 处理A4 心跳异步线程
     * @return
     */
    @Bean("taskExecutor4")
    public Executor taskExecutor4() {
        //自定义线程池
        ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
        pool.setCorePoolSize(hearBeatCorePoolSize); //线程池活跃的线程数,若池中的实际线程数小于该值，无论其中是否有空闲的线程，都会产生新的线程
        pool.setMaxPoolSize(hearBeatMaxPoolSize); //线程池最大活跃的线程数
        //pool.setMaxPoolSize(Integer.MAX_VALUE); //无边界
        pool.setQueueCapacity(hearBeatQueueCapacity);  //<!-- 阻塞队列的容量大小 -->
        pool.setKeepAliveSeconds(hearBeatKeepAliveSeconds);  //<!-- 允许的空闲时间 -->
        pool.setWaitForTasksToCompleteOnShutdown(true);
        /**
         * Reject策略预定义有四种：
         * (1)ThreadPoolExecutor.AbortPolicy策略，是默认的策略,处理程序遭到拒绝将抛出运行时 RejectedExecutionException。
         * (2)ThreadPoolExecutor.CallerRunsPolicy策略 ,调用者的线程会执行该任务,如果执行器已关闭,则丢弃.
         * (3)ThreadPoolExecutor.DiscardPolicy策略，不能执行的任务将被丢弃.
         * (4)ThreadPoolExecutor.DiscardOldestPolicy策略，如果执行程序尚未关闭，则位于工作队列头部的任务将被删除，然后重试执行程序（如果再次失败，则重复此过程）.
         */
        pool.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        pool.setThreadNamePrefix("domain4-");//线程名称前缀
        return pool;
    }


    /**
     * 处理A4 心跳异步线程
     * @return
     */
    @Bean("taskExecutor5")
    public Executor taskExecutor5() {
        //自定义线程池
        ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
        pool.setCorePoolSize(hearBeatCorePoolSize); //线程池活跃的线程数,若池中的实际线程数小于该值，无论其中是否有空闲的线程，都会产生新的线程
        pool.setMaxPoolSize(hearBeatMaxPoolSize); //线程池最大活跃的线程数
        //pool.setMaxPoolSize(Integer.MAX_VALUE); //无边界
        pool.setQueueCapacity(hearBeatQueueCapacity);  //<!-- 阻塞队列的容量大小 -->
        pool.setKeepAliveSeconds(hearBeatKeepAliveSeconds);  //<!-- 允许的空闲时间 -->
        pool.setWaitForTasksToCompleteOnShutdown(true);
        /**
         * Reject策略预定义有四种：
         * (1)ThreadPoolExecutor.AbortPolicy策略，是默认的策略,处理程序遭到拒绝将抛出运行时 RejectedExecutionException。
         * (2)ThreadPoolExecutor.CallerRunsPolicy策略 ,调用者的线程会执行该任务,如果执行器已关闭,则丢弃.
         * (3)ThreadPoolExecutor.DiscardPolicy策略，不能执行的任务将被丢弃.
         * (4)ThreadPoolExecutor.DiscardOldestPolicy策略，如果执行程序尚未关闭，则位于工作队列头部的任务将被删除，然后重试执行程序（如果再次失败，则重复此过程）.
         */
        pool.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        pool.setThreadNamePrefix("domain5-");//线程名称前缀
        return pool;
    }

    /**
     * 处理A5充电中异步线程
     * @return
     */
    @Bean("taskA5Executor1")
    public Executor taskA5Executor1() {
        //自定义线程池
        ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();

        pool.setCorePoolSize(corePoolSize); //线程池活跃的线程数,若池中的实际线程数小于该值，无论其中是否有空闲的线程，都会产生新的线程
        pool.setMaxPoolSize(hearBeatMaxPoolSize); //线程池最大活跃的线程数
        //pool.setMaxPoolSize(Integer.MAX_VALUE); //无边界
        pool.setQueueCapacity(queueCapacity);  //<!-- 阻塞队列的容量大小 -->
        pool.setKeepAliveSeconds(hearBeatKeepAliveSeconds);  //<!-- 允许的空闲时间 -->
        pool.setWaitForTasksToCompleteOnShutdown(true);
        /**
         * Reject策略预定义有四种：
         * (1)ThreadPoolExecutor.AbortPolicy策略，是默认的策略,处理程序遭到拒绝将抛出运行时 RejectedExecutionException。
         * (2)ThreadPoolExecutor.CallerRunsPolicy策略 ,调用者的线程会执行该任务,如果执行器已关闭,则丢弃.
         * (3)ThreadPoolExecutor.DiscardPolicy策略，不能执行的任务将被丢弃.
         * (4)ThreadPoolExecutor.DiscardOldestPolicy策略，如果执行程序尚未关闭，则位于工作队列头部的任务将被删除，然后重试执行程序（如果再次失败，则重复此过程）.
         */
        pool.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        pool.setThreadNamePrefix("taskA5Executor1-");//线程名称前缀
        return pool;
    }


    /**
     * 处理A5充电中异步线程
     * @return
     */
    @Bean("taskA5Executor2")
    public Executor taskA5Executor2() {
        //自定义线程池
        ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();

        pool.setCorePoolSize(corePoolSize); //线程池活跃的线程数,若池中的实际线程数小于该值，无论其中是否有空闲的线程，都会产生新的线程
        pool.setMaxPoolSize(hearBeatMaxPoolSize); //线程池最大活跃的线程数
        //pool.setMaxPoolSize(Integer.MAX_VALUE); //无边界
        pool.setQueueCapacity(queueCapacity);  //<!-- 阻塞队列的容量大小 -->
        pool.setKeepAliveSeconds(hearBeatKeepAliveSeconds);  //<!-- 允许的空闲时间 -->
        pool.setWaitForTasksToCompleteOnShutdown(true);
        /**
         * Reject策略预定义有四种：
         * (1)ThreadPoolExecutor.AbortPolicy策略，是默认的策略,处理程序遭到拒绝将抛出运行时 RejectedExecutionException。
         * (2)ThreadPoolExecutor.CallerRunsPolicy策略 ,调用者的线程会执行该任务,如果执行器已关闭,则丢弃.
         * (3)ThreadPoolExecutor.DiscardPolicy策略，不能执行的任务将被丢弃.
         * (4)ThreadPoolExecutor.DiscardOldestPolicy策略，如果执行程序尚未关闭，则位于工作队列头部的任务将被删除，然后重试执行程序（如果再次失败，则重复此过程）.
         */
        pool.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        pool.setThreadNamePrefix("taskA5Executor2-");//线程名称前缀
        return pool;
    }

    /**
     * 处理A5充电中异步线程
     * @return
     */
    @Bean("taskA5Executor3")
    public Executor taskA5Executor3() {
        //自定义线程池
        ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();

        pool.setCorePoolSize(corePoolSize); //线程池活跃的线程数,若池中的实际线程数小于该值，无论其中是否有空闲的线程，都会产生新的线程
        pool.setMaxPoolSize(hearBeatMaxPoolSize); //线程池最大活跃的线程数
        //pool.setMaxPoolSize(Integer.MAX_VALUE); //无边界
        pool.setQueueCapacity(queueCapacity);  //<!-- 阻塞队列的容量大小 -->
        pool.setKeepAliveSeconds(hearBeatKeepAliveSeconds);  //<!-- 允许的空闲时间 -->
        pool.setWaitForTasksToCompleteOnShutdown(true);
        /**
         * Reject策略预定义有四种：
         * (1)ThreadPoolExecutor.AbortPolicy策略，是默认的策略,处理程序遭到拒绝将抛出运行时 RejectedExecutionException。
         * (2)ThreadPoolExecutor.CallerRunsPolicy策略 ,调用者的线程会执行该任务,如果执行器已关闭,则丢弃.
         * (3)ThreadPoolExecutor.DiscardPolicy策略，不能执行的任务将被丢弃.
         * (4)ThreadPoolExecutor.DiscardOldestPolicy策略，如果执行程序尚未关闭，则位于工作队列头部的任务将被删除，然后重试执行程序（如果再次失败，则重复此过程）.
         */
        pool.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        pool.setThreadNamePrefix("taskA5Executor3-");//线程名称前缀
        return pool;
    }

    /**
     * 处理A5充电中异步线程
     * @return
     */
    @Bean("taskA5Executor4")
    public Executor taskA5Executor4() {
        //自定义线程池
        ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();

        pool.setCorePoolSize(corePoolSize); //线程池活跃的线程数,若池中的实际线程数小于该值，无论其中是否有空闲的线程，都会产生新的线程
        pool.setMaxPoolSize(hearBeatMaxPoolSize); //线程池最大活跃的线程数
        //pool.setMaxPoolSize(Integer.MAX_VALUE); //无边界
        pool.setQueueCapacity(queueCapacity);  //<!-- 阻塞队列的容量大小 -->
        pool.setKeepAliveSeconds(hearBeatKeepAliveSeconds);  //<!-- 允许的空闲时间 -->
        pool.setWaitForTasksToCompleteOnShutdown(true);
        /**
         * Reject策略预定义有四种：
         * (1)ThreadPoolExecutor.AbortPolicy策略，是默认的策略,处理程序遭到拒绝将抛出运行时 RejectedExecutionException。
         * (2)ThreadPoolExecutor.CallerRunsPolicy策略 ,调用者的线程会执行该任务,如果执行器已关闭,则丢弃.
         * (3)ThreadPoolExecutor.DiscardPolicy策略，不能执行的任务将被丢弃.
         * (4)ThreadPoolExecutor.DiscardOldestPolicy策略，如果执行程序尚未关闭，则位于工作队列头部的任务将被删除，然后重试执行程序（如果再次失败，则重复此过程）.
         */
        pool.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        pool.setThreadNamePrefix("taskA5Executor4-");//线程名称前缀
        return pool;
    }

    /**
     * 处理A5充电中异步线程
     * @return
     */
    @Bean("taskA5Executor5")
    public Executor taskA5Executor5() {
        //自定义线程池
        ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();

        pool.setCorePoolSize(corePoolSize); //线程池活跃的线程数,若池中的实际线程数小于该值，无论其中是否有空闲的线程，都会产生新的线程
        pool.setMaxPoolSize(hearBeatMaxPoolSize); //线程池最大活跃的线程数
        //pool.setMaxPoolSize(Integer.MAX_VALUE); //无边界
        pool.setQueueCapacity(queueCapacity);  //<!-- 阻塞队列的容量大小 -->
        pool.setKeepAliveSeconds(hearBeatKeepAliveSeconds);  //<!-- 允许的空闲时间 -->
        pool.setWaitForTasksToCompleteOnShutdown(true);
        /**
         * Reject策略预定义有四种：
         * (1)ThreadPoolExecutor.AbortPolicy策略，是默认的策略,处理程序遭到拒绝将抛出运行时 RejectedExecutionException。
         * (2)ThreadPoolExecutor.CallerRunsPolicy策略 ,调用者的线程会执行该任务,如果执行器已关闭,则丢弃.
         * (3)ThreadPoolExecutor.DiscardPolicy策略，不能执行的任务将被丢弃.
         * (4)ThreadPoolExecutor.DiscardOldestPolicy策略，如果执行程序尚未关闭，则位于工作队列头部的任务将被删除，然后重试执行程序（如果再次失败，则重复此过程）.
         */
        pool.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        pool.setThreadNamePrefix("taskA5Executor5-");//线程名称前缀
        return pool;
    }
}
